import {
  IEditorLanguage,
  jsBeautifyOptions,
} from '@/components/Editor/CodeEditorConfig';
import js_beautify from 'js-beautify';
import sqlFormatter from 'sql-formatter-plus';

/**
 * 自动格式化SQL
 * @param code 输入格式化之前的SQL
 * @returns 格式化后的SQL
 */
export function formatSql(code: string = ''): string {
  const codeList = code.split(/;/g);

  let sql = codeList
    .map((item) => {
      return item
        .split(/\s+union all\s+ /gi)
        .map((ctn) => {
          try {
            return sqlFormatter.format(ctn, {
              language: 'sql',
              indent: '  ',
            });
          } catch (error) {
            console.log(error);
            // 解析异常时原样返回
            return ctn;
          }
        })
        .join('\n union all \n');
    })
    .join(';\n');

  // 这是一个bug兼容，有可能还有别的bug，使用时务必留心观察
  // https://github.com/jdorn/sql-formatter/issues/109
  //  When sql code has "!= "operator, formatting code gets wrong syntax formatting"! = ". There is an extra space between the "!" symbol and the "=" symbol

  // sql语句中插入变量是${test},但是格式化后变为$ { test },自动添加了空格
  // 所以在这使用正则匹配去除空格
  // ${}格式去空格
  sql = sql
    .replace(/ !\s*=/g, ' !=')
    .replace(/\s?\$\s+{([^}]*)}/g, function () {
      // replace方法第二个参数是函数时请关注arguments
      return ' ${' + arguments?.[1]?.trim() + '}';
    })
    // .replace(/\s?\$\s*{\s*/g, ' ${')
    .replace(/\s?}\s+_/g, '}_');

  return sql
    .replace(/ !\s*=/g, ' !=')
    .replace(/\s?\$\s*{\s*/g, ' ${')
    .replace(/\s?}\s+_/g, '}_');
}

/** 格式化java、js等 */
export function formatJs(code: string) {
  return js_beautify(code, jsBeautifyOptions);
}

/** 根据不同语言异步格式化 */
export function formatCodeByLanguage(code: string, language?: IEditorLanguage) {
  // 将同步改异步，为长文本处理时添加loading效果
  return new Promise<string>((resolve, reject) => {
    setTimeout(() => {
      let txt = code;
      if (language === 'sql') {
        txt = formatSql(code);
      } else {
        txt = formatJs(code);
      }
      resolve(txt);
    }, 10);
  });
}
